using FrameworkBase;
using UnityEngine;
using UnityEngine.UI;

namespace CounterApp
{
    public class CounterViewController : MonoBehaviour, IController
    {
        private IModelCounter _modelCounter;
        
        // Start is called before the first frame update
        private void Start()
        {
            _modelCounter = GetArchitecture().GetModel<IModelCounter>();
            
            _modelCounter.Count.OnValueChanged += OnCountChanged;
            
            // 主动调用一次
            OnCountChanged(_modelCounter.Count.Value);
            
            transform.Find("BtnAdd").GetComponent<Button>().onClick.AddListener(() =>
            {
                // 交互逻辑 View -> Model
                new CommandAddCount()
                    .Execute();
            });
            
            transform.Find("BtnSub").GetComponent<Button>().onClick.AddListener(() =>
            {
                // 交互逻辑 View -> Model
                new CommandSubCount()
                    .Execute();
            });
        }

        private void OnCountChanged(int newCount)
        {
            transform.Find("TextCount").GetComponent<Text>().text = newCount.ToString();
        }

        private void OnDestroy()
        {
            _modelCounter.Count.OnValueChanged -= OnCountChanged;

            _modelCounter = null;
        }
        
        public IArchitecture GetArchitecture()
        {
            return CounterApp.Instance;
        }
    }

    public interface IModelCounter : IModel
    {
        BindableProperty<int> Count { get; }
    }

    public class ModelCounter : AbstractModel, IModelCounter
    {
        // 通过实现继承自 IBelongToArchitecture 的 IModel 的 Init() 接口，替换掉构造方法的方法体，防止 ModelCounter 的递归初始化
        // 后来，IModel 的 Init() 接口被阉割了，子类实现 OnInit() 即可
        protected override void OnInit()
        {
            // 使用 Architecture.GetUtility 替代 CounterApp.Get，防止 ModelCounter 的递归初始化
            var storage = GetArchitecture().GetUtility<IStorage>();
            
            Count.Value = storage.LoadInt("COUNTER_COUNT", 0);

            Count.OnValueChanged += count => { storage.SaveInt("COUNTER_COUNT", count); };
        }

        public BindableProperty<int> Count { get; } = new BindableProperty<int>()
        {
            Value = 0
        };
    }
}